Skip to content

feat: add --reverse flag to temporal workflow show#988

Open
veeral-patel wants to merge 1 commit intomainfrom
veeral/workflow-show-reverse
Open

feat: add --reverse flag to temporal workflow show#988
veeral-patel wants to merge 1 commit intomainfrom
veeral/workflow-show-reverse

Conversation

@veeral-patel
Copy link
Copy Markdown

What changed?

This PR adds a --reverse flag to the temporal workflow show command that fetches Event History newest-event-first via WorkflowService.GetWorkflowExecutionHistoryReverse. Useful for inspecting recent activity on long-running workflows without pulling the full history from the beginning.

Files changed

File Change
internal/temporalcli/commands.yaml Added reverse bool option under temporal workflow show
internal/temporalcli/commands.gen.go Regenerated via make gen — adds Reverse field and --reverse flag registration
internal/temporalcli/commands.workflow_view.go Rejects --reverse + --follow; passes reverse and namespace into the history iterator
internal/temporalcli/commands.workflow_exec.go Extended structuredHistoryIter with a reverse code path that pages through GetWorkflowExecutionHistoryReverse; skips continue-as-new traversal in reverse mode
internal/temporalcli/commands.workflow_view_test.go Added tests for tabular reverse output, JSON reverse output, and --reverse --follow rejection

How did you test it?

  • built
  • run locally and tested manually
  • added new unit test(s)
  • added new integration test(s) — not applicable
  • added new functional test(s) — not applicable (CLI change)

Unit tests

Test case Input Expected
Tabular reverse order Completed workflow (≥2 events), --reverse WorkflowExecutionCompleted prints before WorkflowExecutionStarted in stdout
JSON reverse order Completed workflow, --reverse -o json Parsed events[].eventId is strictly decreasing across the array
Rejects --follow --reverse --follow Command exits non-zero with error --reverse cannot be combined with --follow

Manual tests

Setup

./temporal server start-dev --headless
./temporal workflow start --type ManualReverseTest --task-queue rev-test --workflow-id rev-1 --input '"hello"'
./temporal workflow signal --workflow-id rev-1 --name ping
./temporal workflow signal --workflow-id rev-1 --name ping --input '"second"'
./temporal workflow terminate --workflow-id rev-1 --reason "manual test"

Forward (default) vs reverse — tabular

$ ./temporal workflow show --workflow-id rev-1
Progress:
  ID           Time                     Type
    1  ...                  WorkflowExecutionStarted
    2  ...                  WorkflowTaskScheduled
    3  ...                  WorkflowExecutionSignaled
    4  ...                  WorkflowExecutionSignaled
    5  ...                  WorkflowExecutionTerminated

$ ./temporal workflow show --workflow-id rev-1 --reverse
Progress:
  ID           Time                     Type
    5  ...                  WorkflowExecutionTerminated
    4  ...                  WorkflowExecutionSignaled
    3  ...                  WorkflowExecutionSignaled
    2  ...                  WorkflowTaskScheduled
    1  ...                  WorkflowExecutionStarted

Events are listed newest-first when --reverse is set.

JSON reverse

$ ./temporal workflow show --workflow-id rev-1 --reverse -o json | jq '[.events[].eventId]'
["5", "4", "3", "2", "1"]

eventId values are strictly decreasing, matching reverse order.

Detailed reverse

$ ./temporal workflow show --workflow-id rev-1 --reverse --detailed | grep -E '^-+ \['
--------------- [5] WorkflowExecutionTerminated ---------------
--------------- [4] WorkflowExecutionSignaled ---------------
--------------- [3] WorkflowExecutionSignaled ---------------
--------------- [2] WorkflowTaskScheduled ---------------
--------------- [1] WorkflowExecutionStarted ---------------

Per-event detail sections are rendered in reverse order.

Reject --follow

$ ./temporal workflow show --workflow-id rev-1 --reverse --follow
Error: --reverse cannot be combined with --follow
$ echo $?
1

Nonexistent workflow

$ ./temporal workflow show --workflow-id does-not-exist --reverse
Progress:
  ID           Time                     Type
Error: displaying history failed: workflow not found for ID: does-not-exist
$ echo $?
1

Error-path behavior is unchanged from the forward implementation.

Fetches Event History newest-event-first via WorkflowService.GetWorkflowExecutionHistoryReverse, useful for inspecting recent activity on long-running workflows without pulling the full history.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
@veeral-patel veeral-patel requested a review from a team as a code owner April 20, 2026 21:46
@CLAassistant
Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

Comment thread internal/temporalcli/commands.workflow_exec.go
@veeral-patel veeral-patel requested a review from yycptt April 27, 2026 23:26
"--follow",
)
s.Error(res.Err)
s.ErrorContains(res.Err, "--reverse cannot be combined with --follow")
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not something for this PR, but it would be nice to have a way to generate MarkFlagsMutuallyExclusive in the yaml file below.

Seems like this is not currently supported for auto-gen but something the under lying framework supports.

return nil, nil
}
s.reverseStarted = true
resp, err := s.client.WorkflowService().GetWorkflowExecutionHistoryReverse(
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the default page size. For large history would be nice to allow customers to provide a custom size.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the max page size configured on the server side is 256 (batches) I think.

return nil, nil
}
s.reverseStarted = true
resp, err := s.client.WorkflowService().GetWorkflowExecutionHistoryReverse(
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the max page size configured on the server side is 256 (batches) I think.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants